﻿using System;
using System.Collections.Generic;
using System.Linq;
using LM.InterfacesFabricas.Interfaces.Repositorios;
using LM.Negocio.Objetos;
using LM.InterfacesFabricas.Basicos.Enumeradores;

namespace LM.Negocio.Validadores
{
    public class ValidadorDeTelefone : ValidadorAbastrato
    {
        private Telefone _objetoValidado;

        private IRepositorioDeConsultaDeObjetos<Telefone> _repositorioDeTelefone;

        public ValidadorDeTelefone(IRepositorioDeConsultaDeObjetos<Telefone> repositorioDeTelefone)
        {
            if (repositorioDeTelefone == null)
            {
                throw new ArgumentNullException("repositorioDeTelefone");
            }

            _repositorioDeTelefone = repositorioDeTelefone;
        }

        public ValidadorDeTelefone() {}

        public void ValideCadastro(Telefone Telefone)
        {
            if (Telefone == null)
            {
                throw new ArgumentException("Telefone");
            }

            _objetoValidado = Telefone;
            base.LimpeInconsistencias();

            ValideCodigoNaoInformado();
            ValideDddNaoInformado();
            ValideNumeroNaoInformado();
            ValideTelefoneJaCadastrada();

            base.GarantaSucesso();
        }

        public void ValideTelefoneLista(Telefone Telefone)
        {
            if (Telefone == null)
            {
                throw new ArgumentException("Telefone");
            }

            _objetoValidado = Telefone;
            base.LimpeInconsistencias();

            ValideCodigoNaoInformado();
            ValideDddNaoInformado();
            ValideNumeroNaoInformado();

            base.GarantaSucesso();
        }

        public void ValideAtualizacao(Telefone Telefone)
        {
            if (Telefone == null)
            {
                throw new ArgumentException("Telefone");
            }

            _objetoValidado = Telefone;
            base.LimpeInconsistencias();

            ValideCodigoNaoInformado();
            ValideDddNaoInformado();
            ValideNumeroNaoInformado();
            ValideTelefoneNaoCadastrada();

            base.GarantaSucesso();
        }

        public void ValideExclusao(Telefone Telefone)
        {
            if (Telefone == null)
            {
                throw new ArgumentException("Telefone");
            }

            _objetoValidado = Telefone;
            base.LimpeInconsistencias();

            ValideTelefoneNaoCadastrada();

            base.GarantaSucesso();
        }

        private void ValideCodigoNaoInformado()
        {
            if (_objetoValidado.Codigo == 0)
            {
                AdicioneInconsistencia("Código não informado.");
            }
        }

        private void ValideDddNaoInformado()
        {
            if (_objetoValidado.Ddd == 0)
            {
                AdicioneInconsistencia("Ddd não informado.");
            }
        }

        private void ValideNumeroNaoInformado()
        {
            if (string.IsNullOrWhiteSpace(_objetoValidado.Numero))
            {
                AdicioneInconsistencia("Número não informado.");
            }
        }

        private void ValideTipoDeTelefoneNaoInformado()
        {
            if (!Enum.IsDefined(typeof(EnumTipoDeTelefone), _objetoValidado.TipoDeTelefone))
            {
                AdicioneInconsistencia("Tipo de telefone não informado.");
            }
        }

        private bool TelefoneJaCadastrada()
        {
            return _repositorioDeTelefone.Consulte(m => m.Codigo == _objetoValidado.Codigo).Any();
        }

        public bool TelefoneJaCadastrada(Telefone telefone)
        {
            return _repositorioDeTelefone.Consulte(m => m.Codigo == telefone.Codigo).Any();
        }


        private void ValideTelefoneJaCadastrada()
        {
            if (TelefoneJaCadastrada())
            {
                AdicioneInconsistencia("Já existe um Telefone cadastrada com o código {0}.", _objetoValidado.Codigo);
            }
        }
        
        private void ValideTelefoneNaoCadastrada()
        {
            if (!TelefoneJaCadastrada())
            {
                AdicioneInconsistencia("Telefone com o código {0} não cadastrada.", _objetoValidado.Codigo);
            }
        }
    }
}
